package generic.swing;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

/**
 * A Generic panel used for any username/password login dialogue box.
 *
 * This is NOT designed to do anything by itself. It is meant to be derived
 * from to create your own login dialogue.
 *
 * @author Adam Scarr
 */
public class LoginDialogue extends JDialog {
    protected JLabel errorMsg = new JLabel("Invalid username or password", JLabel.CENTER);
    protected JTextField username;
    protected JPasswordField password;
    protected JButton login;
    protected JButton cancel;
    private ActionListener listener = null;

    /**
     * Class Constructor.
     */
    public LoginDialogue() {
        username = new JTextField(10);
        password = new JPasswordField(10);
        login = new JButton("Login");
        login.setSize(0, 15);
        cancel = new JButton("Cancel");
        JLabel usernameLabel = new JLabel("Username:", JLabel.RIGHT);
        JLabel passwordLabel = new JLabel("Password:", JLabel.RIGHT);

        setTitle("Login");

        errorMsg.setForeground(Color.RED);

        // Create the username/password panel.
        JPanel loginPanel = new JPanel(new GridLayout(2, 2, 5, 5));
        add(loginPanel, BorderLayout.CENTER);

        loginPanel.add(usernameLabel);
        loginPanel.add(username);
        loginPanel.add(passwordLabel);
        loginPanel.add(password);

        // Create a flowLayout for the buttons at the bottom.
        JPanel buttons = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        add(buttons, BorderLayout.SOUTH);

        buttons.add(login);
        buttons.add(cancel);

        // Set it up so enter will log us in.
        getRootPane().setDefaultButton(login);

        // Center the frame on the screen.
        pack();
        Dimension screensize = Toolkit.getDefaultToolkit().getScreenSize();
        int centerX = (int)(screensize.getWidth() - getWidth()) / 2;
        int centerY = (int)(screensize.getHeight() - getHeight()) / 2;
        setLocation(centerX, centerY);

        setResizable(false);

        // Cancel button will hide the window and clear the text.
        cancel.addActionListener(
        new ActionListener() {
            public void actionPerformed(ActionEvent actionEvent) {
                username.setText("");
                password.setText("");
                setVisible(false);
            }
        }
        );
    }

    /**
     * Gets the current contents of the password box.
     * @return the content of the password box.
     */
    public String getPassword() {
        return new String(password.getPassword());
    }

    /**
     * Gets the username currently in the password box.
     * @return The content of the username box.
     */
    public String getUsername() {
        return username.getText();
    }

    /**
     * Sets the listener to be used when the Login button is clicked.
     * @param al    The action listener to be called.
     */
    public void setLoginListener(ActionListener al) {
        if (listener != null) {
            login.removeActionListener(listener);
        }

        listener = al;
        login.addActionListener(al);
    }

    /**
     * Toggle the visibility of the error message.
     * @param visible   if true the error box is visible, otherwise hides it.
     */
    public void setErrorVisible(boolean visible) {
        if (visible) {
            add(errorMsg, BorderLayout.NORTH);
        } else {
            remove(errorMsg);
        }
        pack();
    }

    /**
     * Makes the login box visible and resets its fields.
     */
    public void open() {
        username.setText("");
        password.setText("");
        setVisible(true);
    }

    /**
     * Hides the login box and resets its fields.
     */
    public void close() {
        username.setText("");
        password.setText("");
        setVisible(false);
    }
}
